﻿using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using System.Collections.Generic;
using ElCamino.AspNet.Identity.AzureTable;
using ElCamino.AspNet.Identity.AzureTable.Model;
using Microsoft.WindowsAzure;
using CloudStorageLight.Core;
using CloudStorageLight.Core.Web;
using Microsoft.WindowsAzure.Storage.Table;
using System;

namespace CloudStorageLight.Web.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        private IList<string> roles { get; set; }

        //public bool IsAdmin { get { return roles.Any(x=>x == BlobUser.AdminRoleName); } }
        //public IEnumerable<string> Groups { get { return roles.Where(x => x != BlobUser.AdminRoleName); } }
        public IEnumerable<string> Groups { get { return roles; } }

        public string CellPhoneNo { get; set; }

        public async Task EnsureRolesAsync(UserManager<ApplicationUser> manager)
        {
            if (roles == null) roles = await manager.GetRolesAsync(this.Id);
        }
    }

 
    public class ApplicationDbContext : IdentityCloudContext<ApplicationUser>
    {
        public ApplicationDbContext(string domain=null)
            : base( new IdentityConfiguration() { StorageConnectionString = SystemSettings.Instance.BlobStorage, TablePrefix = domain ?? BlobService.GetCurrentDomain() })
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }

        public List<string> GetUsers(string query)
        {
            var q = new TableQuery<QueryUserTable>();
            var tbl = this.UserTable.ExecuteQuery<QueryUserTable>(q).ToList();
            IEnumerable<string> ids;
            if (!string.IsNullOrEmpty(query))
            {
                ids = tbl.Where(x => (x.Email != null && x.Email.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) >= 0)
                                        || (x.RoleName != null && x.RoleName.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) >= 0))
                    .Select(x => x.PartitionKey).Distinct();
            }
            else
            {
                ids = tbl.Select(x => x.PartitionKey).Distinct();
            }
            return tbl.Where(x => x.Email != null && ids.Any(y => x.PartitionKey == y)).Select(x => x.Email).Distinct().OrderBy(x => x).ToList();
        }

        public List<string> GetGroups()
        {
            var query = new TableQuery<IdentityRole>();
            //return IdentityContent.RoleTable.ExecuteQuery(query).Where(x => x.Name != BlobUser.AdminRoleName).Select(x => x.Name).Distinct().OrderBy(x => x).ToList();
            return this.RoleTable.ExecuteQuery(query).Select(x => x.Name).Distinct().OrderBy(x => x).ToList();
        }

        public void AddGroups(string group)
        {
            var identity = new IdentityRole(group);
            identity.GenerateKeys();
            TableOperation insertOperation = TableOperation.Insert(identity);
            this.RoleTable.Execute(insertOperation);
        }


    }

    public class QueryUserTable : TableEntity
    {
        public string RoleName { get; set; }
        public string Email { get; set; }
        public Boolean? EmailConfirmed { get; set; }

    }


}